﻿using System;

namespace ADEVSO.IO
{
    public static class Directory
    {
        #region Methods

        /// <summary>
        /// Create File Path if it doesn't exits
        /// </summary>
        /// <param name="fileName"></param>
        public static void CreatePath(String fileName)
        {
            if (! System.IO.Directory.Exists(fileName))
            {
                String[] filePathArray = fileName.Split(new char[] { '\\' });
                String filePath = filePathArray[0];
                for (int i = 1; i < filePathArray.Length - 1; i++)
                    filePath += "\\" + filePathArray[i];
                System.IO.Directory.CreateDirectory(filePath);
            }
        }

        /// <summary>
        /// Create a Directory Path
        /// </summary>
        /// <param name="path"></param>
        public static void CreateDirectoryPath(String path)
        {
            if (System.IO.Directory.GetParent(path).Exists)
                System.IO.Directory.CreateDirectory(path);
            else CreateDirectoryPath(System.IO.Directory.GetParent(path).FullName);
        }

        /// <summary>
        /// Get Computer Logical Drives
        /// </summary>
        /// <returns></returns>
        public static ADEVSO.Collections.ArrayList GetLogicalDrives()
        {
            ADEVSO.Collections.ArrayList report = new ADEVSO.Collections.ArrayList();
            String[] drives = System.IO.Directory.GetLogicalDrives();
            foreach (String drive in drives)
                report.Add(drive);
            return report;
        }

        /// <summary>
        /// Get SubCarpets on Carpet
        /// </summary>
        /// <param name="carpetName"></param>
        /// <returns></returns>
        public static ADEVSO.Collections.ArrayList GetSubCarpetsOnCarpet(String carpetName)
        {
            ADEVSO.Collections.ArrayList report = new ADEVSO.Collections.ArrayList();
            String[] dirs = null;
            try
            {
                dirs = System.IO.Directory.GetDirectories(carpetName);
                foreach (String dir in dirs)
                    report.Add(dir);
            }
            catch { }
            return report;
        }

        /// <summary>
        /// Get Files on Carpet
        /// </summary>
        /// <param name="carpetName"></param>
        /// <returns></returns>
        public static ADEVSO.Collections.ArrayList GetFilesOnCarpet(String carpetName)
        {
            ADEVSO.Collections.ArrayList report = new ADEVSO.Collections.ArrayList();
            String[] files = null;
            try
            {
                files = System.IO.Directory.GetFiles(carpetName);
                foreach (String i in files)
                    report.Add(i);
            }
            catch { }

            return report;
        }

        /// <summary>
        /// Get Files on Carpet filtering by File Extensions
        /// </summary>
        /// <param name="carpetName"></param>
        /// <param name="exts"></param>
        /// <param name="equals">True: Equals Extensions; False: Similar Extensions</param>
        /// <returns></returns>
        public static ADEVSO.Collections.ArrayList GetFilesOnCarpet(String carpetName, ADEVSO.Collections.ArrayList exts, bool equals)
        {
            ADEVSO.Collections.ArrayList report = new ADEVSO.Collections.ArrayList();
            String[] files = System.IO.Directory.GetFiles(carpetName);
            foreach (String i in files)
                if (ADEVSO.IO.File.IsRequiredExtension(i, exts, equals))
                    report.Add(i);
            return report;
        }

        /// <summary>
        /// Get Files on Carpet and SubCarpets
        /// </summary>
        /// <param name="carpetName"></param>
        /// <returns></returns>
        public static ADEVSO.Collections.ArrayList GetFilesOnCarpetAndSubCarpets(String carpetName)
        {
            ADEVSO.Collections.ArrayList report = new ADEVSO.Collections.ArrayList();

            // Gets Files on Actual Carpet
            ADEVSO.Collections.ArrayList files = GetFilesOnCarpet(carpetName);
            for (int i = 0; i < files.Count; i++)
                report.Add(files[i]);

            // Get SubCarpets on Actual Carpet
            ADEVSO.Collections.ArrayList carpets = GetSubCarpetsOnCarpet(carpetName);
            for (int i = 0; i < carpets.Count; i++)
            {
                // Get Files on Actual SubCarpet
                ADEVSO.Collections.ArrayList filesTemp = GetFilesOnCarpetAndSubCarpets(carpets[i].ToString());
                for (int x = 0; x < filesTemp.Count; x++)
                    report.Add(filesTemp[x]);
            }

            return report;
        }

        /// <summary>
        /// /// Get Files on Carpet and SubCarpets filtering by File Extensions
        /// </summary>
        /// <param name="carpetName"></param>
        /// <param name="exts"></param>
        /// <param name="equals">True: Equals Extensions; False: Similar Extensions</param>
        /// <returns></returns>
        public static ADEVSO.Collections.ArrayList GetFilesOnCarpetAndSubCarpets(String carpetName, ADEVSO.Collections.ArrayList exts, bool equals)
        {
            ADEVSO.Collections.ArrayList report = new ADEVSO.Collections.ArrayList();

            // Gets Files on Actual Carpet
            ADEVSO.Collections.ArrayList files = GetFilesOnCarpet(carpetName);
            for (int i = 0; i < files.Count; i++)
                if (ADEVSO.IO.File.IsRequiredExtension(files[i].ToString(), exts, equals))
                    report.Add(files[i]);

            // Get SubCarpets on Actual Carpet
            ADEVSO.Collections.ArrayList carpets = GetSubCarpetsOnCarpet(carpetName);
            for (int i = 0; i < carpets.Count; i++)
            {
                // Get Files on Actual SubCarpet
                ADEVSO.Collections.ArrayList filesTemp = GetFilesOnCarpetAndSubCarpets(carpets[i].ToString(), exts, equals);
                for (int x = 0; x < filesTemp.Count; x++)
                    report.Add(filesTemp[x]);
            }

            return report;
        }

        /// <summary>
        /// Get Complete File Paths
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="initialPath"></param>
        /// <returns></returns>
        public static ADEVSO.Collections.ArrayList GetFilePaths(String fileName, String initialPath)
        {
            ADEVSO.Collections.ArrayList report = new ADEVSO.Collections.ArrayList();

            // Gets Files on Actual Carpet
            ADEVSO.Collections.ArrayList files = GetFilesOnCarpet(initialPath);
            for (int i = 0; i < files.Count; i++)
            {
                if (files[i].ToString().EndsWith(fileName))
                {
                    report.Add(files[i]);
                    return report;
                }
            }

            // Get SubCarpets on Actual Carpet
            ADEVSO.Collections.ArrayList carpets = GetSubCarpetsOnCarpet(initialPath);
            for (int i = 0; i < carpets.Count; i++)
            {
                // Get Files on Actual SubCarpet
                ADEVSO.Collections.ArrayList filesTemp = GetFilePaths(fileName, carpets[i].ToString());
                for (int x = 0; x < filesTemp.Count; x++)
                    report.Add(filesTemp[x]);
            }

            return report;
        }

        /// <summary>
        /// Get Complete Files Paths
        /// </summary>
        /// <param name="filesNames"></param>
        /// <param name="initialPath"></param>
        /// <returns></returns>
        public static ADEVSO.Collections.ArrayList GetFilesPaths(ADEVSO.Collections.ArrayList filesNames, String initialPath)
        {
            ADEVSO.Collections.ArrayList report = new ADEVSO.Collections.ArrayList();
            // Busca los Paths Completos del Archivo
            for (int i = 0; i < filesNames.Count; i++)
            {
                ADEVSO.Collections.ArrayList temp = GetFilePaths(filesNames[i].ToString(), initialPath);
                for (int x = 0; x < temp.Count; x++)
                    report.Add(temp[i]);
            }
            return report;
        }

        /// <summary>
        /// Get Complete File Path
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="directoryFiles"></param>
        /// <returns></returns>
        private static String GetFilePath(String fileName, ADEVSO.Collections.ArrayList directoryFiles)
        {
            for (int i = 0; i < directoryFiles.Count; i++)
                if (directoryFiles[i].ToString().EndsWith(fileName))
                    return directoryFiles[i].ToString();
            return null;
        }

        /// <summary>
        /// Get Complete Files Path
        /// </summary>
        /// <param name="filesNames"></param>
        /// <param name="initialPath"></param>
        /// <returns></returns>
        public static ADEVSO.Collections.ArrayList GetFilesPath(ADEVSO.Collections.ArrayList filesNames, String initialPath)
        {
            ADEVSO.Collections.ArrayList report = new ADEVSO.Collections.ArrayList();
            ADEVSO.Collections.ArrayList directoryFiles = GetFilesOnCarpetAndSubCarpets(initialPath);
            // Get Complete File Path
            for (int i = 0; i < filesNames.Count; i++)
            {
                String temp = GetFilePath(filesNames[i].ToString(), directoryFiles);
                if (temp != null)
                    report.Add(temp);
            }
            return report;
        }

        /// <summary>
        /// Remove File/Directory Path
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static String RemovePath(String path)
        {
            String temp = "";
            // If is a file or a directory
            if (System.IO.File.Exists(path) || System.IO.Directory.Exists(path))
            {
                String[] splits = path.Split(new char[] { '\\' });
                temp = splits.GetValue(splits.Length - 1).ToString();
            }
            else throw new Exception("The file/directory don't exists.");
            return temp;
        }

        /// <summary>
        /// Get File/Directory Path
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static String GetPath(String path)
        {
            String temp = "";
            // If is a file or a directory
            if (System.IO.File.Exists(path) || System.IO.Directory.Exists(path))
            {
                String[] splits = path.Split(new char[] { '\\' });
                for (int i = 0; i < splits.Length - 1; i++)
                    temp += splits.GetValue(i) + "\\";
            }
            else throw new Exception("The file didn't exists.");
            return temp;
        }

        /// <summary>
        /// Replace Files Source Path
        /// </summary>
        /// <param name="files">Files Paths</param>
        /// <param name="sourcePath">Source Path</param>
        /// /// <param name="newSourcePath">New Source Path</param>
        public static ADEVSO.Collections.ArrayList ReplaceSourcePath(ADEVSO.Collections.ArrayList files, String sourcePath, String newSourcePath)
        {
            for (int i = 0; i < files.Count; i++)
                files[i] = files[i].ToString().Replace(sourcePath, newSourcePath);
            return files;
        }

        /// <summary>
        /// Rename Directory
        /// </summary>
        /// <param name="directoryName">Complete Directory Name (with path)</param>
        /// <param name="newDirectoryName">New Directory Name (with path)</param>
        public static void Rename(String directoryName, String newDirectoryName)
        {
            if (System.IO.Directory.Exists(directoryName))
            {
                if (System.IO.Directory.Exists(newDirectoryName))
                {
                    try
                    {
                        System.IO.Directory.Move(directoryName, newDirectoryName + "\\" + RemovePath(newDirectoryName));
                    }
                    catch
                    {
                        throw new Exception("Invalid new directory name");
                    }
                }
                else
                {
                    try
                    {
                        CreatePath(newDirectoryName);
                        System.IO.Directory.Move(directoryName, newDirectoryName);
                    }
                    catch
                    {
                        throw new Exception("Invalid new directory name");
                    }
                }
            }
            else
            {
                throw new Exception("The directory don't exits");
            }
        }

        #endregion
    }
}
